﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tracy.DataModel;
using System.Net;
using System.IO;
using Tracy.BTParser;
using SharedLib.MessageFramework;
using SharedLib.MessageFramework.Messages;
using SharedLib;
using SharedLib.MessageFramework.Handlers;

namespace Tracy.Handlers
{
    public class AssignMediaFileHandler : TaskMessageHandler
    {
        public static event EventHandler<GenericEventArgs<IList<MediaFile>>> MediaFileAssigned;
        protected override void ProcessMessage(TaskMessage msg)
        {
            if (msg != null)
            {
                Resource res = msg.Data as Resource;
                if (res != null)
                {
                    IList<MediaFile> files = ParseResource(res);
                    msg.Result = files;
                    MediaFileAssigned.InvokeEvent(this, new GenericEventArgs<IList<MediaFile>>(files));
                }
            }
        }

        private List<MediaFile> ParseResource(Resource res)
        {
            List<MediaFile> rtn = new List<MediaFile>();
            string type = res.GetResourceType();
            if (type == "BT")
            {
                //Download and Parse bit torrent file
                string tempFile = Path.GetTempPath() + res.GetFileName();
                WebClient client = new WebClient();
                try
                {
                    client.DownloadFile(res.Url, tempFile);
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException("Failed to download torrent file from " + res.Url + " to local path " + tempFile, ex);
                }
                res.Attributes["local-torrent-file"] = tempFile; //Pass local torrent file location to downloader
                Torrent t = new Torrent(tempFile);
                res.Attributes["torrent-name"] = t.Name;
                //TODO: Current BT Parser will treat these two cases as the same: no multiple file structure / multiple file structure with one file, which should be improved for different downloaders
                string locationBase = (t.FileNameList.Count > 1) ? t.Name + "\\" : "";//Folder will be required if there are multiple files
                
                List<string> existingFileNames = new List<string>();
                //Pass existing files
                foreach (MediaFile existingFile in TracyFacade.Instance.MediaFileProvider.GetItemsByResource(res))
                {
                    existingFileNames.Add(existingFile.FileName);
                }

                for (int i = t.FileNameList.Count -1; i >= 0; i--)
                {
                    string fileName = t.FileNameList[i] as string;
                    if (!existingFileNames.Contains(fileName))
                    {
                        if (MediaFile.WillDownload(fileName))
                        {
                            int lastSlashIndex = fileName.LastIndexOf("\\");
                            string location = (lastSlashIndex > 0) ? locationBase + fileName.Substring(0, lastSlashIndex) : locationBase;
                            MediaFile newFile = BuildMediaFile(res, fileName.Substring(lastSlashIndex + 1), location);
                            //TracyBus.Instance.MediaFileProvider.AddItem(newFile);
                            rtn.Add(newFile);
                        }
                    }
                }
                //File.Delete(tempFile);
            }
            else if (type == "Emule") //Emule
            {
                MediaFile newFile = BuildMediaFile(res, TracyFacade.Instance.DownloadManager.GetValidFileName(res.Title, type), null);
                //TracyBus.Instance.MediaFileProvider.AddItem(newFile);
                rtn.Add(newFile);
            }
            //TODO: Other type
            return rtn;
        }

        private static MediaFile BuildMediaFile(Resource res, string fileName, string location)
        {
            MediaFile newFile = new MediaFile();
            newFile.Resource = res;
            newFile.FileName = fileName;
            if(!string.IsNullOrEmpty(location)) newFile.Location = location;
            newFile.Properties[MediaFile.KEY_DOWNLOAD_PATH] = TracyFacade.Instance.DownloadManager.GetDownloadFolder(newFile);
            if (MediaFile.IsVisible(fileName)) newFile.Visible = "true";
            return newFile;
        }
    }
}
